/* Turska Framework/UI library (Turs2)
 * Copyright 2003-2010 Jetro Lauha
 * All rights reserved.
 * Web: http://iki.fi/jetro/turska/
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of EITHER:
 *   (1) The GNU Lesser General Public License as published by the Free
 *       Software Foundation; either version 2.1 of the License, or (at
 *       your option) any later version. The text of the GNU Lesser
 *       General Public License is included with this library in the
 *       file LICENSE-LGPL.txt.
 *   (2) The BSD-style license that is included with this library in
 *       the file LICENSE-BSD.txt.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
 * LICENSE-LGPL.txt and LICENSE-BSD.txt for more details.
 *
 * $Id: T2IMGUIImageButtonStyle.cpp 28 2012-07-28 17:03:06Z trzntaat $
 * $Revision: 28 $
 */

#include <assert.h>

#include "Turs2.h"


namespace turska
{


IMGUIImageButtonStyle::IMGUIImageButtonStyle(Font *font, Image *imageUp, Image *imageHot,
                                             Image *imageActive, Image *imageDown) :
    mScale(1),
    mImageWidth(0), mImageHeight(0),
    mShadowEnabled(false),
    mTextXOffset(0), mTextYOffset(0),
    mImageXOffset(0), mImageYOffset(0),
    mShadowXOffset(0), mShadowYOffset(2.5f),
    mButtonDownTextXOffset(0), mButtonDownTextYOffset(2.0f),
    mButtonDownImageXOffset(0), mButtonDownImageYOffset(2.0f),
    mTextFlags(IF_ALIGN_CENTER), mImageFlags(IF_ALIGN_CENTER),
    mTextDrawMode(IDM_NORMAL), mImageDrawMode(IDM_NORMAL),
    mTextScale(1), mKeyFocusAllowed(true), mActivateFromUpEvent(true),
    mButtonImageDrawMode(IDM_NORMAL)
{
    mButtonColor.set(0xffffffff);
    mImageColor.set(0xffffffff);
    mTextColor.set(0xffffffff);
    mShadowMultiplierColor.set(0x80000000);
    mFont = font;
    mImages[IMGUI_WS_DEFAULT] = imageUp;
    mImages[IMGUI_WS_HOT] = imageHot;
    mImages[IMGUI_WS_ACTIVE] = imageActive;
    mImages[IMGUI_WS_HOT_ACTIVE] = imageDown;
    Image *img = mImages[IMGUI_WS_DEFAULT];
    if (img == 0)
        img = mImages[IMGUI_WS_HOT];
    if (img == 0)
        img = mImages[IMGUI_WS_ACTIVE];
    if (img == 0)
        img = mImages[IMGUI_WS_HOT_ACTIVE];
    if (img != 0)
    {
        mImageWidth = (UI32)img->getWidth();
        mImageHeight = (UI32)img->getHeight();
    }
}


TREAL IMGUIImageButtonStyle::getWidth()
{
    return mScale * mImageWidth;
}

TREAL IMGUIImageButtonStyle::getHeight()
{
    if (mImageHeight)
        return mScale * mImageHeight;
    else if (mFont)
        return mFont->getFontHeight(mScale);
    else
        return 0;
}


bool IMGUIImageButtonStyle::isInside(const IMGUI &imgui, TREAL x, TREAL y,
                                     const Rectangle &area,
                                     const C8 *text, Image *image)
{
    const bool haveCustomArea = (area.width != 0 && area.height != 0);
    x -= area.x;
    y -= area.y;
    if (!haveCustomArea)
    {
        if (mImageWidth > 0 && mImageHeight > 0)
            return x >= 0 && y >= 0 &&
                   x < mImageWidth * mScale && y < mImageHeight * mScale;
        else if (image != 0)
            return x >= 0 && y >= 0 &&
                   x < image->getWidth() * mScale && y < image->getHeight() * mScale;
        else if (text != 0)
        {
            TREAL stringW, stringH;
            mFont->getStringMetrics(stringW, stringH, text, mScale, 0, 0);
            return x >= 0 && y >= 0 && x < stringW && y < stringH;
        }
    }
    return x >= 0 && y >= 0 && x < area.width && y < area.height;
}


Rectangle IMGUIImageButtonStyle::render(const IMGUI &imgui, I32 widgetState,
                                        TREAL x, TREAL y, TREAL width, TREAL height,
                                        const C8 *text, Image *image)
{
    assert(widgetState >= 0 && widgetState < IMGUI_WS_COUNT);
    const bool renderingEnabled = imgui.isRenderingEnabled();
    Image *buttonImage = mImages[widgetState];
    UI32 defaultFlags = IF_COLOR | IF_ALPHA;
    if (mScale != TREAL(1))
        defaultFlags |= IF_TRANSFORM | IF_SCALE;
    else
        defaultFlags |= IF_FORCE_INT;
    const bool haveCustomArea = (width != 0 && height != 0);
    if (!haveCustomArea)
    {
        if (buttonImage != 0)
        {
            if (renderingEnabled)
            {
                buttonImage->setScale(mScale);
                buttonImage->draw(mButtonImageDrawMode, defaultFlags, x, y, mButtonColor);
            }
            width = mScale * mImageWidth;
            height = mScale * mImageHeight;
        }
        else if (image != 0)
        {
            width = mScale * image->getWidth();
            height = mScale * image->getHeight();
        }
        else if (text != 0 && mFont != 0)
        {
            mFont->getStringMetrics(width, height, text, mScale, 0, 0);
        }
    } // !haveCustomArea
    Rectangle resultArea(x, y, width, height);

    const TREAL tlx = x, tly = y; // default align is top left
    TREAL tx = tlx, ty = tly;
    if (mTextFlags & IF_ALIGN_HORIZ_CENTER)
        tx += width / 2;
    else if (mTextFlags & IF_ALIGN_RIGHT)
        tx += width;
    if (mTextFlags & IF_ALIGN_VERT_CENTER)
        ty += height / 2;
    else if (mTextFlags & IF_ALIGN_BOTTOM)
        ty += height;
    tx = (TREAL)((I32)(tx + mTextXOffset));
    ty = (TREAL)((I32)(ty + mTextYOffset));
    TREAL ix = tlx, iy = tly;
    if (mImageFlags & IF_ALIGN_HORIZ_CENTER)
        ix += width / 2;
    else if (mImageFlags & IF_ALIGN_RIGHT)
        ix += width;
    if (mImageFlags & IF_ALIGN_VERT_CENTER)
        iy += height / 2;
    else if (mImageFlags & IF_ALIGN_BOTTOM)
        iy += height;
    ix = (TREAL)((I32)(ix + mImageXOffset));
    iy = (TREAL)((I32)(iy + mImageYOffset));

    if (mShadowEnabled)
    {
        TREAL shadowX = mScale * mShadowXOffset;
        TREAL shadowY = mScale * mShadowYOffset;

        // image/text shadow
        if (renderingEnabled && image != 0)
        {
            image->setScale(mScale);
            image->draw(IDM_NORMAL, defaultFlags | mImageFlags,
                        ix + shadowX, iy + shadowY, mShadowMultiplierColor);
        }
        if (renderingEnabled && mFont != 0 && text != 0)
        {
            mFont->drawText(tx + shadowX, ty + shadowY, text, mTextFlags,
                            mScale * mTextScale, 0, mShadowMultiplierColor, 0);
        }
    }

    // image/text itself
    if (widgetState == IMGUI_WS_HOT_ACTIVE)
    {
        tx += mScale * mButtonDownTextXOffset;
        ty += mScale * mButtonDownTextYOffset;
        ix += mScale * mButtonDownImageXOffset;
        iy += mScale * mButtonDownImageYOffset;
    }
    if (renderingEnabled && image != 0)
    {
        image->setScale(mScale);
        image->draw(mImageDrawMode, defaultFlags | mImageFlags, ix, iy, mImageColor);
    }
    if (renderingEnabled && mFont != 0 && text != 0)
    {
        const IMAGE_DRAW_MODE orgDrawMode = mFont->getDrawMode();
        mFont->setDrawMode(mTextDrawMode);
        mFont->drawText(tx, ty, text, mTextFlags, mScale * mTextScale, 0, mTextColor, 0);
        mFont->setDrawMode(orgDrawMode);
    }

    // Possible TODO: highlight text/image when hot
    if (widgetState & IMGUI_WS_MASK_HOT)
    {
    }

    if (buttonImage == 0)
    {
        // button area is defined by text/image, match result
        // area to the adjusted coordinates
        resultArea.x = tlx;
        resultArea.y = tly;
    }

    return resultArea;
}


} // namespace turska
